/***************************************************************************
 *           mainwindow - Debug GUI for Minorite remote development
 *
 *  Fri Apr 23 08:10:56 2010
 *  Copyright  2010  Christophe Seyve
 *  Email cseyve@free.fr
 ****************************************************************************/

/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMovie>

#include "minrem_imageproc.h"

#include <cv.h>
#include <cv.hpp>
#include <cvaux.h>
#include <highgui.h>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindowClass)
{

    ui->setupUi(this);

	connect(&m_timer, SIGNAL(timeout()), this, SLOT(on_m_timer_timeout()));
}

MainWindow::~MainWindow()
{
    delete ui;
}
CvCapture* capture = 0;

void MainWindow::on_playButton_clicked() {
	fprintf(stderr, "MainWindow::%s:%d ! \n", __func__, __LINE__);
	if(m_timer.isActive()) {
		m_timer.stop();

		return;
	}


	if(!capture) {
		capture = cvCaptureFromFile( "/home/tof/Vision/MinorityRemote/dataset/PhilipsToUCamPro2.avi");
		fprintf(stderr, "%s:%d : capture=%p\n", __func__, __LINE__, capture);
	}
	if(!capture) { return ; }

	if(!m_timer.isActive()) {
		m_timer.start(100);
	}

}

void MainWindow::on_webcamButton_clicked() {
	fprintf(stderr, "MainWindow::%s:%d ! \n", __func__, __LINE__);
	if(m_timer.isActive()) {
		m_timer.stop();
		return;
	}


	if(!capture) {
		capture = cvCaptureFromCAM( NULL );
		fprintf(stderr, "%s:%d : capture=%p\n", __func__, __LINE__, capture);
		cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);
		cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 240);
		cvSetCaptureProperty(capture, CV_CAP_PROP_FPS, 10);
	}

	if(!capture) { return ; }

	if(!m_timer.isActive()) {
		m_timer.start(100);
	}

}

typedef uint8_t u8;
typedef uint32_t u32;

static u32 * grey_colortable = NULL;

QImage iplImageToQImage(IplImage * iplImage) {
	if(!iplImage)
		return QImage();


	int depth = iplImage->nChannels;
	QImage frameImage(iplImage->width, iplImage->height, QImage::Format_RGB32);//frame->nChannels*8);
	if(!frameImage.isNull()) {
		// Copy buffer
		uint8_t * display = (uint8_t *)frameImage.bits();
		int pitch = frameImage.width() * 4;

		memset(display, 0xFF, pitch*iplImage->height);

		uint8_t * data = (uint8_t*)iplImage->imageData;

		switch(depth) {

		default:
		case 4: // copy
			for(int r = 0; r<iplImage->height; r++) {
				memcpy(display + r*pitch,
					   data + r*iplImage->widthStep,
					   iplImage->width);
			}
			break;
		case 3: // revert RGB => BGR
			for(int r = 0; r<iplImage->height; r++) {
				u8 * bgr32 = (u8 *)(display + r*pitch);
				u8 * rgb24 = (u8 *)data + r * iplImage->widthStep;
				for(int c = 0; c<iplImage->width; c++, rgb24+=3, bgr32+=4) {
					bgr32[2] = rgb24[0];
					bgr32[1] = rgb24[1];
					bgr32[0] = rgb24[2];
				}
			}
			break;
		case 1:
			if(!grey_colortable ) {
				grey_colortable  = new u32 [256];
				for(int g = 0; g<256; g++) {
					u8 grey = (u8)g;

					memset(&grey_colortable[g], grey, sizeof(u32));
/*					grey_colortable[g] = ( (u32)0xff0000ff
											 | (grey<<16)
											 | (grey<<8)
											 | (grey) );
											 */
				}
			}

			for(int r = 0; r<iplImage->height; r++) {
				u32 * color = (u32 *)(display + r*pitch);
				u8 * grey = (u8 *)(data + r * iplImage->widthStep);

				for(int c = 0; c<iplImage->width; c++) {
					color[c] = grey_colortable[(int)grey[c]];
//					color[0] =
//							color[1] =
//							color[2] =
//							grey[c];
				}
			}
			break;
		}
	}

	return frameImage;
}

/// Minority Remote image processing class
MinRemImageProc m_imgProc;

void MainWindow::on_m_timer_timeout() {
//fprintf(stderr, "MainWindow::%s:%d ! \n", __func__, __LINE__);
	// Grab image
	if( !cvGrabFrame( capture ) ) {
		fprintf(stderr, "%s:%d : capture=%p FAILED => stop timer\n", __func__, __LINE__, capture);
		m_timer.stop();
		// release capture
		cvReleaseCapture(&capture);
		capture = NULL;
		return;
	} else {
		IplImage * frame = cvRetrieveFrame( capture );
		//computeWAF( frame );
		// Display frame
		QImage frameImage = iplImageToQImage(frame);
		if(!frameImage.isNull()) {

			ui->outputLabel->setPixmap(QPixmap::fromImage(frameImage));

			// Display it in ui
/*			QImage displayImage = frameImage.scaled(ui->movieLabel->size(), Qt::IgnoreAspectRatio);
			fprintf(stderr, "MainWindow::%s:%d display %dx%dx%d! \n",
					__func__, __LINE__,
					displayImage.width(), displayImage.height(), displayImage.depth()
					);
	*/
		}

		// Process input image
		m_imgProc.processImage(frame);

		//
		IplImage * debugImage = m_imgProc.getDebugImage();
				//m_imgProc.getGrownImage();
		if(debugImage) {
			QImage displayImage = iplImageToQImage(debugImage);
			ui->movieLabel->setPixmap(QPixmap::fromImage(displayImage));
		}

		if(m_imgProc.getMotionHistoImage()) {
			QImage displayImage = iplImageToQImage(m_imgProc.getMotionHistoImage());
			ui->histoLabel->setPixmap(QPixmap::fromImage(displayImage));
		}

		// get movement direction
		float dx, dy;
		m_imgProc.getMovement(&dx, &dy);

		// draw in sliders
		int val_x = (int)(50.f + dx*50.f);
		int val_y = (int)(50.f + dy*50.f);

		///
		ui->volumeBar->setValue( m_imgProc.getVolume() );

		if(m_imgProc.isPlay())
			ui->playLabel->setText(tr("Play"));
		else
			ui->playLabel->setText(tr("Pause"));


		ui->horizontalSlider->setValue(val_x);
		ui->verticalSlider->setValue(val_y);
	}

}
